package club.cearnach.security.strategy;

import club.cearnach.core.property.MovieSecurityProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.session.InvalidSessionStrategy;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * Session 超时策略
 *
 * @author 阮胜
 * @date 2018/5/23 15:58
 */
@Slf4j
@Component
public class MovieInvalidSessionStrategy implements InvalidSessionStrategy {
    private final MovieSecurityProperties movieSecurityProperties;
    private String destinationUrl;
    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    private boolean createNewSession = true;


    public MovieInvalidSessionStrategy(MovieSecurityProperties movieSecurityProperties) {
        this.movieSecurityProperties = movieSecurityProperties;
        Assert.isTrue(UrlUtils.isValidRedirectUrl(movieSecurityProperties.getAdminLoginInvalidUrl()),
                "url必须以'/'或'http(s)'开头");
        this.destinationUrl = movieSecurityProperties.getAdminLoginInvalidUrl();
    }

    @Override
    public void onInvalidSessionDetected(HttpServletRequest request,
                                         HttpServletResponse response) throws IOException {
        if (createNewSession) {
            request.getSession();
        }
        String uri = request.getRequestURI();
        log.info("Invalid session , redirectUri = " + uri);
        destinationUrl = uri;
        if (movieSecurityProperties.getAdminLoginPageUrl().equalsIgnoreCase(uri)) {
            destinationUrl = movieSecurityProperties.getAdminLoginPageUrl();
        } else if (movieSecurityProperties.getAdminLoginExpiredUrl().equalsIgnoreCase(uri)) {
            destinationUrl = movieSecurityProperties.getAdminLoginExpiredUrl();
        }
        redirectStrategy.sendRedirect(request, response, destinationUrl);

    }

    /**
     * 确定是否应该在重定向之前创建一个新会话
     * 以避免可能的循环问题，即使用重定向发送同一个会话ID请求
     * 或者，确保配置的URL不会通过
     *
     * @param createNewSession 默认为true.
     */
    public void setCreateNewSession(boolean createNewSession) {
        this.createNewSession = createNewSession;
    }
}
